package com.labofjet.messagesender.service.impl;

import com.labofjet.common.service.impl.BaseServiceImpl;
import com.labofjet.common.util.ConverterUtils;
import com.labofjet.common.util.IdUtils;
import com.labofjet.message.dto.MsgMessageSenderDto;
import com.labofjet.message.dto.MsgMessageSenderExample;
import com.labofjet.message.dto.MsgMessageSenderResultDto;
import com.labofjet.message.enums.EMessageReceiverDicType;
import com.labofjet.message.enums.EMessageSendProgressDicType;
import com.labofjet.message.mapper.MsgMessageSenderMapper;
import com.labofjet.messagesender.entity.MsgMessageSenderResultCmp;
import com.labofjet.messagesender.repository.MsgMessageSenderResultRepository;
import com.labofjet.messagesender.service.SdrMessageSenderService;
import com.labofjet.system.dto.SysRoleDto;
import com.labofjet.system.dto.SysUserDto;
import com.labofjet.system.enums.EResult;
import com.labofjet.system.service.impl.SysUserServiceImpl;
import com.labofjet.system.util.FreeMarkerUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

public abstract class SdrBaseMessageSenderServiceImpl extends BaseServiceImpl implements SdrMessageSenderService {

	@Autowired
	private MsgMessageSenderMapper msgMessageSenderMapper;

	@Autowired
	private SysUserServiceImpl sysUserService;

	@Autowired
	protected MsgMessageSenderResultRepository msgMessageSenderResultRepository;

	@Override
	public MsgMessageSenderDto handle(MsgMessageSenderDto msgMessageSenderDto) {
		// 接受到消息,更新状态
		msgMessageSenderDto.setProgress(EMessageSendProgressDicType.HADNLE.getCode());
		this.updateMessageState(msgMessageSenderDto); // 不需要开事务

		// 查找要发送的user
		String receiver = msgMessageSenderDto.getReceiver();
		String receiverType = msgMessageSenderDto.getReceiverType();
		List<SysUserDto> users = new ArrayList<>();
		if (EMessageReceiverDicType.USER.getCode().equals(receiverType)) {
			SysUserDto sysUserDto = new SysUserDto();
			sysUserDto.setUsername(receiver);
			SysUserDto user = sysUserService.findByUsername(sysUserDto);
			if (user != null) {
				users.add(user);
			}
		} else if (EMessageReceiverDicType.ROLE.getCode().equals(receiverType)) {
			SysRoleDto sysRoleDto = new SysRoleDto();
			sysRoleDto.setSn(receiver);
			List<SysUserDto> userList = sysUserService.findByRole(sysRoleDto);
			if (CollectionUtils.isNotEmpty(userList)) {
				users.addAll(userList);
			}
		}

		// 发送并保存记录
		boolean errorOccur = false; // 发送了错误?
		for (SysUserDto user : users) {
			MsgMessageSenderResultDto one = new MsgMessageSenderResultDto();
			one.setUsername(user.getUsername());
			one.setId(IdUtils.uuid());
			one.setDate(new Date());
			one.setSn(msgMessageSenderDto.getSn());
			try {
				this.handlerInternal(msgMessageSenderDto, user);
				one.setResult(EResult.SUCC.getCode());
				save(one);
			} catch (Exception e) {
				errorOccur = true;
				log.error("发送信息失败 MsgMessageSenderDto:{}, SysUserDto:{}", msgMessageSenderDto, user);
				log.error("发送信息失败 详情:", e);
				one.setResult(EResult.FAIL.getCode());
				one.setFailMessage(e.getMessage());
				save(one);
				if (!continueIfError()) {
					break;
				}
			}
		}

		// 更新状态
		if (errorOccur) {
			msgMessageSenderDto.setProgress(EMessageSendProgressDicType.ERROR.getCode());
			this.updateMessageState(msgMessageSenderDto); // 不需要开事务
		} else {
			msgMessageSenderDto.setProgress(EMessageSendProgressDicType.FINISH.getCode());
			this.updateMessageState(msgMessageSenderDto); // 不需要开事务
		}
		return msgMessageSenderDto;
	}

	/**
	 * 处理具体的发送逻辑
	 *
	 * @return
	 */
	protected abstract MsgMessageSenderDto handlerInternal(MsgMessageSenderDto msgMessageSenderDto, SysUserDto sysUserDto);

	/**
	 * 保存发送的信息
	 */
	protected MsgMessageSenderResultCmp save(MsgMessageSenderResultDto msgMessageSenderResultDto) {
		return msgMessageSenderResultRepository.save(ConverterUtils.convertOne(msgMessageSenderResultDto, new MsgMessageSenderResultCmp()));
	}

	/**
	 * 一条信息出错的是否继续发送剩下的
	 *
	 * @return
	 */
	protected boolean continueIfError() {
		return true;
	}

	/**
	 * 更新mysql表sender的状态
	 *
	 * @param msgMessageSenderDto
	 * @return
	 */
	protected MsgMessageSenderDto updateMessageState(MsgMessageSenderDto msgMessageSenderDto) {
		MsgMessageSenderExample msgMessageSenderExample = new MsgMessageSenderExample();
		msgMessageSenderExample.createCriteria().andSnEqualTo(msgMessageSenderDto.getSn());
		MsgMessageSenderDto entity = new MsgMessageSenderDto();
		entity.setProgress(msgMessageSenderDto.getProgress());
		msgMessageSenderMapper.updateByExampleSelective(entity, msgMessageSenderExample);
		return msgMessageSenderDto;
	}

	/**
	 * 允许使用一些内置变量
	 *
	 * @param txt
	 * @param msgMessageSenderDto
	 * @param sysUserDtos
	 * @return
	 */
	protected String processText(String txt, MsgMessageSenderDto msgMessageSenderDto, SysUserDto sysUserDtos) {
		Map<String, Object> param = new HashMap<>();
		param.put("to", sysUserDtos.getUsername());
		return FreeMarkerUtil.getProcessValue(param, txt);
	}

}

